class IUP_DIALOG
-- In IUP you can create your own dialogs or use one of the predefined dialogs. 
-- To create your own dialogs you will have to create all the controls of the 
-- dialog before the creation of the dialog. All the controls must be composed 
-- in a hierarchical structure so the root will be used as a parameter to the 
-- dialog creation.
--
-- When a control is created, its parent is not known. After the dialog is 
-- created all elements receive a parent. This mechanism is quite different 
-- from that of native systems, who first create the dialog and then the 
-- element are inserted, using the dialog as a parent. This feature creates 
-- some limitations for IUP, usually related to the insertion and removal of 
-- controls.
--
-- Since the controls are created in a different order from the native system, 
-- native controls can only be created after the dialog. This will happen 
-- automatically when the application call the show function to show the dialog.
-- But we often need the native controls to be created so we can use some other 
-- functionality of those before they are visible to the user. For that 
-- purpose, map function was created. It forces IUP to map the controls to 
-- their native system controls. The show function internally uses map before 
-- showing the dialog on the screen. show can be called many times, but the map 
-- process will occur only once.
--
-- show can be replaced by popup. In this case the result will be a modal 
-- dialog and all the other previously shown dialogs will be unavailable to the 
-- user. Also the program will interrupt in the function call until the 
-- application return IUP_CLOSE or exit_loop is called.
--
-- All dialogs are automatically destroyed in iup_close.
		
inherit
	IUP_CONTAINER
		undefine
			execute_dragbegin,
			execute_dragdatasize,
			execute_dragdata,
			execute_dragend,
			execute_dropdata,
			execute_dropmotion
		redefine
			--	set_maxsize,
			--	get_maxsize,
			--	set_minsize,
			--	get_minsize
			execute_map,
			execute_unmap,
			execute_destroy,
			execute_getfocus,
			execute_killfocus,
			execute_enterwindow,
			execute_leavewindow,
			execute_k_any,
			execute_help,
			execute_close,
			execute_copydata,
			execute_dropfiles,
			execute_mdiactivate,
			execute_move,
			execute_resize,
			execute_show,
			execute_trayclick,
			execute_focus
		end
	IUP_WIDGET_EXPAND
	IUP_WIDGET_TITLE
	IUP_WIDGET_VISIBLE
	IUP_WIDGET_ACTIVE
	IUP_WIDGET_BGCOLOR
	IUP_WIDGET_FONT
	IUP_WIDGET_SCREENPOSITION
	IUP_WIDGET_TIP
	IUP_WIDGET_CLIENTOFFSET
	IUP_WIDGET_CLIENTSIZE
	IUP_WIDGET_RASTERSIZE
	IUP_WIDGET_USERSIZE
	IUP_WIDGET_ZORDER
	IUP_WIDGET_POPUP
	IUP_WIDGET_SHOW
	IUP_WIDGET_HIDE
	IUP_WIDGET_PARENT_DIALOG
	IUP_WIDGET_ICON
	IUP_WIDGET_DEFAULT_ENTER_ESC
	IUP_WIDGET_MAXMIN_SIZE
		redefine
			set_maxsize,
			get_maxsize,
			set_minsize,
			get_minsize
		end
	IUP_DRAG_AND_DROP
	IUP_WIDGET_CUSTOM_ATTRIBUTES

create {ANY}
   dialog

create {IUP}
   dialog_widget

feature {ANY}

	dialog (content: IUP_WIDGET)
		-- Create a new dialog with the specified content
		local
			a_dialog: POINTER
		do
			a_dialog := int_dialog(content.widget)

			set_widget(a_dialog)
      end

	-- Attributes

	get_dialog_child (name: STRING): detachable IUP_WIDGET
		-- Returns the child element that has the NAME attribute equals
		-- to the given value on the dialog. Works also for children 
		-- of a menu that is associated with a dialog.
		-- This function will only found the child if the NAME attribute
		-- is set at the control.
		do
			Result := iup_open.iup_get_dialog_child(Current, name)
		end

	-- Drop button

	get_drop_button: detachable IUP_DROP_BUTTON
		-- If the dialog is associated to a drop button, then return it. 
		-- Otherwise return Void.
		do
			Result := iup_open.get_drop_button_for_dialog(Current)
		end

	-- Skip BACKGROUND attribute

	set_border (state: BOOLEAN)
		-- (non inheritable) (creation only): Shows a resize border around the 
		-- dialog. Default: "YES". BORDER=NO is useful only when RESIZE=NO, 
		-- MAXBOX=NO, MINBOX=NO, MENUBOX=NO and TITLE=NULL, if any of these are 
		-- defined there will be always some border.
		do
			iup_open.set_attribute(Current, "BORDER", boolean_to_yesno(state))
		end

	has_border: BOOLEAN
		-- Border state.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "BORDER")
			Result := yesno_to_boolean(str)
		end

	get_border_width: INTEGER
		-- (non inheritable): returns the border size.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "BORDERSIZE")

			Result := str.to_integer
		end

	set_child_offset (horizontal, vertical: INTEGER)
		-- Allow to specify a position offset for the child. Available for native 
		-- containers only. It will not affect the natural size, and allows to 
		-- position controls outside the client area. Are integer values 
		-- corresponding to the horizontal and vertical offsets, respectively, 
		-- in pixels. Default: 0x0.
		require
			horizontal >= 0
			vertical >= 0
		local
			offset: STRING
		do
			offset := horizontal.out
			offset.append_string("x")
			offset.append_string(vertical.out)

			iup_open.set_attribute(Current, "CHILDOFFSET", offset)
		end

	get_child_offset: TUPLE[INTEGER, INTEGER]
		-- Return the offset of the child.
		local
			offset: STRING
		do
			offset := iup_open.get_attribute(Current, "CHILDOFFSET")
			Result := components_of_size(offset)
		end

	set_cursor (name: STRING)
		-- Defines the element's cursor. See documentation. Default: ARROW
		do
			iup_open.set_attribute(Current, "CURSOR", name)
		end

	get_cursor: STRING
		-- Return the cursor name.
		do
			Result := iup_open.get_attribute(Current, "CURSOR")
		end

	set_nactive (state: BOOLEAN)
		-- (non inheritable): same as set_active but does not affects the 
		-- controls inside the dialog. 
		do
			iup_open.set_attribute(Current, "NACTIVE", boolean_to_yesno(state))
		end

	is_nactive: BOOLEAN
		-- Return the state of nactive.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "NACTIVE")
			Result := yesno_to_boolean(str)
		end

	set_size (width, height: INTEGER)
		-- (non inheritable): Dialog’s size.
		--
		-- The dialog Natural size is only considered when the User size is not 
		-- defined or when it is bigger than the Current size. This behavior is 
		-- different from a control that goes inside the dialog. Because of that, 
		-- when SIZE or RASTERSIZE are set (changing the User size), the Current 
		-- size is internally reset to 0x0, so the the Natural size can be 
		-- considered when re-computing the Current size of the dialog.
		--
		-- Values set at SIZE or RASTERSIZE attributes of a dialog are always 
		-- accepted, regardless of the minimum size required by its children. For 
		-- a dialog to have the minimum necessary size to fit all elements 
		-- contained in it, simply define SIZE or RASTERSIZE to NULL. Also if you 
		-- set SIZE or RASTERSIZE to be used as the initial size of the dialog, 
		-- its contents will be limited to this size as the minimum size, if you 
		-- do not want that, then after showing the dialog reset this size to NULL
		-- so the dialog can be resized to smaller values. But notice that its 
		-- contents will still be limited by the Natural size, to also remove 
		-- that limitation set SHRINK=True. To only change the User size in 
		-- pixels, without resetting the Current size, set the USERSIZE attribute 
		-- (since 3.12). Notice that the dialog size includes its decoration (it 
		-- is the Window size), the area available for controls are returned by 
		-- the dialog CLIENTSIZE. For more information see Layout Guide.
		local
			size: STRING
		do
			size := width.out
			size.append_string("x")
			size.append_string(height.out)

			iup_open.set_attribute(Current, "SIZE", size)
		end

	set_predefined_size (width, height: STRING)
		-- (non inheritable): Dialog’s size using predefined values 
		-- for width and/or height. However you can combine a predefined 
		-- value with an integer (as string). The predefined values are:
		-- 
		-- "FULL": Defines the dialog’s width (or height) equal to the screen's 
		--         width (or height)
		-- "HALF": Defines the dialog’s width (or height) equal to half the 
		--         screen's width (or height)
		-- "THIRD": Defines the dialog’s width (or height) equal to 1/3 the 
		--         screen's width (or height)
		-- "QUARTER": Defines the dialog’s width (or height) equal to 1/4 of the 
		--         screen's width (or height)
		-- "EIGHTH": Defines the dialog’s width (or height) equal to 1/8 of the 
		--         screen's width (or height)
		require
			is_valid_size (width, height)
		local
			size: STRING
		do
			size := width
			size.append_string("x")
			size.append_string(height)

			iup_open.set_attribute(Current, "SIZE", size)
		end

	get_size: TUPLE[INTEGER, INTEGER]
		-- The size of the dialog.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "SIZE")
			Result := components_of_size(str)
		end

	set_simulate_modal (state: BOOLEAN)
		-- Disable all other visible dialogs, just like when the dialog is made
		-- modal.
		do
			iup_open.set_attribute(Current, "SIMULATEMODAL", boolean_to_yesno(state))
		end

	-- Exclusive

	-- Skip CUSTOMFRAMESIMULATE

	set_modal_dialog_frame (state: BOOLEAN)
		-- Set the common decorations for modal dialogs. This means RESIZE=NO, 
		-- MINBOX=NO and MAXBOX=NO. In Windows, if the PARENTDIALOG is defined 
		-- then the MENUBOX is also removed, but the Close button remains.
		do
			iup_open.set_attribute(Current, "DIALOGFRAME", boolean_to_yesno(state))
		end

	is_modal_dialog_frame: BOOLEAN
		-- Modal dialog.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "DIALOGFRAME")
			Result := yesno_to_boolean(str)
		end

	set_fullscreen (state: BOOLEAN)
		-- Makes the dialog occupy the whole screen over any system bars in the 
		-- main monitor. All dialog details, such as title bar, borders, maximize 
		-- button, etc, are removed. Possible values: True, False. In Motif you 
		-- may have to click in the dialog to set its focus.
		-- In Motif if set to Trur when the dialog is hidden, then it can not be 
		-- changed after it is visible.
		do
			iup_open.set_attribute(Current, "FULLSCREEN", boolean_to_yesno(state))
		end

	get_fullscreen: BOOLEAN
		-- Fullscreen status
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "FULLSCREEN")
			Result := yesno_to_boolean(str)
		end

	set_maxbox (state: BOOLEAN)
		-- (creation only): Requires a maximize button from the window manager. 
		-- If RESIZE=NO then MAXBOX will be set to NO. Default: True. In Motif the
		-- decorations are controlled by the Window Manager and may not be 
		-- possible to be changed from IUP. In Windows MAXBOX is hidden only if 
		-- MINBOX is hidden as well, or else it will be just disabled.
		do
			iup_open.set_attribute(Current, "MAXBOX", boolean_to_yesno(state))
		end

	set_maxsize (width, height: INTEGER)
		-- Maximum size for the dialog in raster units (pixels). The windowing 
		-- system will not be able to change the size beyond this limit. Default: 
		-- 65535x65535.
		do
   		Precursor (width, height)
   	end

	get_maxsize: TUPLE[INTEGER, INTEGER]
		-- Max size of the dialog.
		do
			Result := Precursor
		end

	set_menu (name: STRING)
		-- Name of a menu. Associates a menu to the dialog as a menu bar. The 
		-- previous menu, if any, is unmapped. Use set_widget_name to 
		-- associate a menu to a name.
		do
			iup_open.set_attribute(Current, "MENU", name)
		end

	set_menu_widget (menu: IUP_MENU)
		-- Set the menu widget to the dialog as a menu bar. The previous menu, if 
		-- any, is unmapped.
		do
			iup_open.set_attribute_widget(Current, "MENU", menu)
		end

	set_menubox (state: BOOLEAN)
		-- (creation only): Requires a system menu box from the window manager. 
		-- If hidden will also remove the Close button. Default: True. In Motif 
		-- the decorations are controlled by the Window Manager and may not be 
		-- possible to be changed from IUP. In Windows if hidden will hide also 
		-- MAXBOX and MINBOX.
		do
			iup_open.set_attribute(Current, "MENUBOX", boolean_to_yesno(state))
		end

	set_minbox (state: BOOLEAN)
		-- (creation only): Requires a minimize button from the window manager. 
		-- Default: True. In Motif the decorations are controlled by the Window 
		-- Manager and may not be possible to be changed from IUP. In Windows 
		-- MINBOX is hidden only if MAXBOX is hidden as well, or else it will be 
		-- just disabled.
		do
			iup_open.set_attribute(Current, "MINBOX", boolean_to_yesno(state))
		end

	set_minsize (width, height: INTEGER)
		-- Minimum size for the dialog in raster units (pixels). The windowing 
		-- system will not be able to change the size beyond this limit. Default: 
		-- 1x1. Some systems define a very minimum size greater than this, for 
		-- instance in Windows the horizontal minimum size includes the window 
		-- decoration buttons.
		do
			Precursor (width, height)
   	end

	get_minsize: TUPLE[INTEGER, INTEGER]
		-- Min size of the dialog.
		do
			Result := Precursor
		end

	is_modal: BOOLEAN
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "MODAL")
			Result := yesno_to_boolean(str)
		end

	set_native_parent (dlg: IUP_DIALOG)
		-- (creation only): Dialog to be used as parent. Used 
		-- only if PARENTDIALOG is not defined.
		do
			iup_open.set_attribute_widget(Current, "NATIVEPARENT", dlg)
		end

	-- Skip placement.

	set_resize (state: BOOLEAN)
		-- (creation only): Allows interactively changing the dialog’s size. 
		-- Default: True. If RESIZE=NO then MAXBOX will be set to NO. In Motif 
		-- the decorations are controlled by the Window Manager and may not be 
		-- possible to be changed from IUP.
		do
			iup_open.set_attribute(Current, "RESIZE", boolean_to_yesno(state))
		end

	set_shrink (state: BOOLEAN)
		-- Allows changing the elements’ distribution when the dialog is smaller 
		-- than the minimum size. Default: False.
		do
			iup_open.set_attribute(Current, "SHRINK", boolean_to_yesno(state))
		end

	set_start_focus (name: STRING)
		-- Name of the element that must receive the focus right after the dialog 
		-- is shown using IupShow or IupPopup. If not defined then the first 
		-- control than can receive the focus is selected. Updated after SHOW_CB 
		-- is called and only if the focus was not changed during the callback.
		do
			iup_open.set_attribute(Current, "STARTFOCUS", name)
		end


	-- Exclusive [System Dependent]
	
	-- Skip HWND
	-- Skip SAVEUNDER	
	-- Skip XWINDOW

	-- The next attributes are Windows and GTK only.
	
	is_active_window: BOOLEAN
		-- [Windows and GTK Only] (read-only): informs if the dialog is the 
		--active window (the window with focus). Can be True or False.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "ACTIVEWINDOW")
			Result := yesno_to_boolean(str)
		end

	-- Skip CUSTOMFRAME

	set_as_drop_files_target (state: BOOLEAN)
		-- [Windows and GTK Only] (non inheritable): Enable or disable the drop 
		-- of files. Default: False, but if DROPFILES_CB is defined when the 
		-- element is mapped then it will be automatically enabled.
		do
			iup_open.set_attribute(Current, "DROPFILESTARGET", boolean_to_yesno(state))
		end

	is_drop_files_target: BOOLEAN
		-- Drop files target state.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "DROPFILESTARGET")
			Result := yesno_to_boolean(str)
		end

	is_maximized: BOOLEAN
		-- [Windows Only] (read-only): indicates if the dialog is maximized. Can 
		-- be True or False.
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "MAXIMIZED")
			Result := yesno_to_boolean(str)
		end

	is_minimized: BOOLEAN
		-- [Windows Only] (read-only): indicates if the dialog is minimized. Can 
		-- be	True or False. 
		local
			str: STRING
		do
			str := iup_open.get_attribute(Current, "MINIMIZED")
			Result := yesno_to_boolean(str)
		end

	set_opacity (value: INTEGER)
		-- [Windows and GTK Only]: sets the dialog transparency alpha value. 
		-- Valid values range from 0 (completely transparent) to 255 (opaque). In 
		-- Windows must be set before map so the native window would be properly 
		-- initialized when mapped
		require
			value >= 0
			value <= 255
		do
			iup_open.set_attribute(Current, "OPACITY", value.out)
		end

	set_opacity_image (name: STRING)
		-- [Windows and GTK Only]: sets a transparent image as the dialog shape so
		-- it is possible to create a non rectangle window. In Windows must be 
		-- set before map so the native window would be properly initialized when 
		-- mapped. In GTK the shape works only as a bitmap mask, to view a color 
		-- image must also use a label.
		do
			iup_open.set_attribute(Current, "OPACITYIMAGE", name)
		end

	set_shape_image (name: STRING)
		-- [Windows and GTK Only]: sets a RGBA image as the dialog shape so it is 
		-- possible to create a non rectangle window with children. (GTK 2.12) 
		-- Only the fully transparent pixels will be transparent. The pixels 
		-- colors will be ignored, only the alpha channel is used.
		do
			iup_open.set_attribute(Current, "SHAPEIMAGE", name)
		end

	set_top_most (state: BOOLEAN)
		-- [Windows and GTK Only]:  puts the dialog always in front of all other 
		-- dialogs in all applications. Default: False.
		do
			iup_open.set_attribute(Current, "TOPMOST", boolean_to_yesno(state))
		end

	-- Exclusive Taskbar and Tray/Status Area [Windows and GTK Only]

	set_hide_taskbar (state: BOOLEAN)
		-- [Windows and GTK Only] (write-only): Action attribute that when set to 
		-- "YES", hides the dialog, but does not decrement the visible dialog 
		-- count, does not call SHOW_CB and does not mark the dialog as hidden 
		-- inside IUP. It is usually used to hide the dialog and keep the tray 
		-- icon working without closing the main loop. It has the same effect as 
		-- setting LOCKLOOP=Yes and normally hiding the dialog. IMPORTANT: when 
		-- you hide using HIDETASKBAR, you must show using HIDETASKBAR also. 
		-- Possible values: True, False.
		do
			iup_open.set_attribute(Current, "HIDETASKBAR", boolean_to_yesno(state))
		end

	-- Skip TASKBARPROGRESS, TASKBARPROGRESSSTATE, TASKBARPROGRESSVALUE

	show_task_bar_button
		-- [Windows Only]: Force the application button to be shown on 
		-- the taskbar even if the dialog does not have decorations.
		do
			iup_open.set_attribute(Current, "TASKBARBUTTON", "SHOW")
		end

	hide_task_bar_button
		-- [Windows Only]: Force the application button to be hidden from the taskbar,
		--	but also in this case the system menu, the maximize and minimize buttons 
		--	will be hidden.
		do
			iup_open.set_attribute(Current, "TASKBARBUTTON", "HIDE")
		end

	set_tray (state: BOOLEAN)
		-- [Windows and GTK Only]: When set to "True", displays an icon on the 
		-- system tray.
		do
			iup_open.set_attribute(Current, "TRAY", boolean_to_yesno(state))
		end

	set_tray_image (name: STRING)
		-- [Windows and GTK Only]: Name of a IUP image to be used as the tray 
		-- icon. The Windows SDK recommends that cursors and icons should be 
		-- implemented as resources rather than created at run time.
		do
			iup_open.set_attribute(Current, "TRAYIMAGE", name)
		end

	set_tray_tip (text: STRING)
		-- [Windows and GTK Only]: Tray icon's tooltip text.
		do
			iup_open.set_attribute(Current, "TRAYTIP", text)
		end

	-- Skip TRAYTIPMARKUP, TRAYTIPBALLOON, TRAYTIPBALLOONDELAY, 
	-- TRAYTIPBALLOONTITLE, TRAYTIPBALLOONTITLEICON


	-- Exclusive [GTK Only]

	set_dialog_hint (state: BOOLEAN)
		-- [GTK Only] (creation-only): if enabled sets the window type hint to a 
		-- dialog hint.
		do
			iup_open.set_attribute(Current, "DIALOGHINT", boolean_to_yesno(state))
		end

	set_hide_title_bar (state: BOOLEAN)
		-- [GTK Only] (non inheritable): hides the title bar with all its 
		-- elements. (since 3.20) (GTK 3.10)
		do
			iup_open.set_attribute(Current, "HIDETITLEBAR",
										  boolean_to_yesno(state))
		end


	-- Exclusive [Windows Only]

	set_bring_front (state: BOOLEAN)
		-- [Windows Only] (write-only): makes the dialog the foreground window. 
		-- Use "True" to activate it. Useful for multithreaded applications.
		do
			iup_open.set_attribute(Current, "BRINGFRONT", boolean_to_yesno(state))
		end

	set_composited (state: BOOLEAN)
		-- [Windows Only] (creation only): controls if the window will have an 
		-- automatic double buffer for all children. Default is "False". In 
		-- Windows Vista it is NOT working as expected.
		do
			iup_open.set_attribute(Current, "COMPOSITED", boolean_to_yesno(state))
		end

	-- Skip CONTROL
	-- Skip CUSTOMFRAMEDRAW, CUSTOMFRAMECAPTIONHEIGHT, CUSTOMFRAMECAPTIONLIMITS

	set_help_button (state: BOOLEAN)
		-- [Windows Only] (creation only): Inserts a help button in the same 
		-- place of the maximize button. It can only be used for dialogs without 
		-- the minimize and maximize buttons, and with the menu box. For the next 
		-- interaction of the user with a control in the dialog, the callback  
		-- HELP_CB will be called instead of the control defined ACTION callback. 
		-- Possible values: True, False. Default: False.
		do
			iup_open.set_attribute(Current, "HELPBUTTON", boolean_to_yesno(state))
		end

	set_maximize_at_parent (state: BOOLEAN)
		-- [Windows Only]: when using multiple monitors, maximize the dialog 
		-- in the same monitor that the parent dialog is. 
		do
			iup_open.set_attribute(Current, "MAXIMIZEATPARENT", boolean_to_yesno(state))
		end

	set_toolbox (state: BOOLEAN)
		-- [Windows Only] (creation only): makes the dialog look like a toolbox 
		-- with a smaller title bar. It is only valid if the PARENTDIALOG or 
		-- NATIVEPARENT attribute is also defined. Default: False.
		do
			iup_open.set_attribute(Current, "TOOLBOX", boolean_to_yesno(state))
		end

	-- Exclusive MDI [Windows Only]

	set_mdi_frame (state: BOOLEAN)
		--(creation only) [Windows Only] (non inheritable): Configure this dialog 
		-- as a MDI frame. Can be True or False. Default: False.
		do
			iup_open.set_attribute(Current, "MDIFRAME", boolean_to_yesno(state))
		end

	get_mdi_active: STRING
		-- [Windows Only] (read-only): Returns the name of the current active MDI 
		-- child. Use get_attribute_handle to directly retrieve the child 
			-- widget.
		do
			Result := iup_open.get_attribute(Current, "MDIACTIVE")
		end

	set_mdi_activate (name: STRING)
		-- [Windows Only] (write-only): Name of a MDI child window to be 
		-- activated. If value is "NEXT" will activate the next window after the 
		-- current active window. If value is "PREVIOUS" will activate the 
		-- previous one.
		do
			iup_open.set_attribute(Current, "MDIACTIVATE", name)
		end

	set_mdi_arrange (type: STRING)
		-- [Windows Only] (write-only): Action to arrange MDI child windows. 
		-- Possible values: TILEHORIZONTAL, TILEVERTICAL, CASCADE and ICON 
		-- (arrange the minimized icons).
		require
			is_valid_type(type)
		do
			iup_open.set_attribute(Current, "MDIARRANGE", type)
		end

	set_mdi_close_all
		-- [Windows Only] (write-only): Action to close and destroy all MDI child 
		-- windows. The CLOSE_CB callback will be called for each child.
		-- IMPORTANT: When a MDI child window is closed it is automatically 
		-- destroyed. The application can override this returning IUP_IGNORE in 
		-- CLOSE_CB.	
		do
			iup_open.set_attribute(Current, "MDICLOSEALL", "YES")
		end

	get_mdi_next: STRING
		-- [Windows Only] (read-only): Returns the name of the next available 
		-- MDI child. Use get_attribute_handle to directly retrieve the child 
		-- widget. Must use MDIACTIVE to retrieve the first child. If the 
		-- application is going to destroy the child retrieve the next child 
		-- before destroying the current.
		do
			Result := iup_open.get_attribute(Current, "MDINEXT")
		end

	-- For the MDI Client MDICLIENT and MDIMENU see IUP_CANVAS

	set_mdi_child (state: BOOLEAN)
		-- (creation only) [Windows Only]: Configure this dialog to be a MDI 
		-- child. The PARENTDIALOG attribute must also be defined. Each MDI child 
		-- is automatically named if it does not have one. Default: "False".
		do
			iup_open.set_attribute(Current, "MDICHILD", boolean_to_yesno(state))
		end

	-- Commands to handle callbacks

	-- Common
	set_cb_map (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
		-- Called right after an element is mapped and its attributes updated.
		local
			operation: INTEGER
		do
			cb_map := act
			
			if cb_map /= Void then
				operation := 1
			else
				operation := 0
			end
						
			iup_open.set_callback (Current, "MAP_CB", "NONEEDED", operation)
		end

	set_cb_unmap (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
		-- Called right before an element is unmapped.
		local
			operation: INTEGER
		do
			cb_unmap := act

			if cb_unmap /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "UNMAP_CB", "NONEEDED", operation)
		end

	set_cb_destroy (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
		-- Called right before an element is destroyed.
		local
			operation: INTEGER
		do
			cb_destroy := act

			if cb_destroy /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "DESTROY_CB", "NONEEDED", operation)
		end

	set_cb_get_focus (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
		-- Action generated when an element is given keyboard focus. 
		-- This callback is called after the KILLFOCUS_CB of the element 
		-- that loosed the focus. The {IUP}.get_focus function during the 
		-- callback returns the element that loosed the focus.
		local
			operation: INTEGER
		do
			cb_getfocus := act

			if cb_getfocus /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "GETFOCUS_CB", "NONEEDED", operation)
		end

	set_cb_kill_focus (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
		-- Action generated when an element loses keyboard focus. This 
		-- callback is called before the GETFOCUS_CB of the element that 
		-- gets the focus.
		local
			operation: INTEGER
		do
			cb_killfocus := act

			if cb_killfocus /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "KILLFOCUS_CB", "NONEEDED", operation)
		end

	set_cb_enter_window (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
		-- Action generated when the mouse enters the native element. 
		local
			operation: INTEGER
		do
			cb_enterwindow := act

			if cb_enterwindow /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "ENTERWINDOW_CB", "NONEEDED", operation)
		end

	set_cb_leave_window (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
		-- Action generated when the mouse leaves the native element.
		local
			operation: INTEGER
		do
			cb_leavewindow := act

			if cb_leavewindow /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "LEAVEWINDOW_CB", "NONEEDED", operation)
		end

	set_cb_k_any (act: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER], STRING])
		-- Action generated when a keyboard event occurs.
		-- IUP_WIDGET the element that activated the event.
		-- INTEGER identifier of typed key. Please refer to the Keyboard 
		-- Codes table for a list of possible values.
		--
		-- Returns: If IUP_IGNORE is returned the key is ignored and not
		-- processed by the control and not propagated. If returns 
		-- IUP_CONTINUE, the key will be processed and the event will be
		-- propagated to the parent of the element receiving it, this is 
		-- the default behavior. If returns IUP_DEFAULT the key is processed 
		-- but it is not propagated. IUP_CLOSE will be processed. 
		local
			operation: INTEGER
		do
			cb_k_any := act

			if cb_k_any /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "K_ANY", "NONEEDED", operation)
		end

	set_cb_help (act: detachable PROCEDURE[TUPLE[IUP_DIALOG]])
		-- Action generated when the user press F1 at a control. In Motif 
		-- is also activated by the Help button in some workstations 
		-- keyboard.
		-- Returns: IUP_CLOSE will be processed.
		local
			operation: INTEGER
		do
			cb_help := act

			if cb_help /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "HELP_CB", "NONEEDED", operation)
		end

	-- Extra
	set_cb_close (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
		local
			operation: INTEGER
		do
			cb_close := act

			if cb_close /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "CLOSE_CB", "NONEEDED", operation)
		end

	set_cb_copy_data (act: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING, INTEGER], STRING])
		local
			operation: INTEGER
		do
			cb_copydata := act

			if cb_copydata /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "COPYDATA_CB", "NONEEDED", operation)
		end

	set_cb_drop_files (act: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING, INTEGER, INTEGER, INTEGER], STRING])
		local
			operation: INTEGER
		do
			cb_dropfiles := act

			if cb_dropfiles /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "DROPFILES_CB", "NONEEDED", operation)
		end

	set_cb_mdi_activate (act: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING])
		local
			operation: INTEGER
		do
			cb_mdiactivate := act

			if cb_mdiactivate /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "MDIACTIVATE_CB", "NONEEDED", operation)
		end

	set_cb_move (act: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER], STRING])
		local
			operation: INTEGER
		do
			cb_move := act

			if cb_move /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "MOVE_CB", "NONEEDED", operation)
		end

	set_cb_resize (act: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER], STRING])
		local
			operation: INTEGER
		do
			cb_resize := act

			if cb_resize /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "RESIZE_CB", "NONEEDED", operation)
		end

	set_cb_show (act: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING], STRING])
		local
			operation: INTEGER
		do
			cb_show := act

			if cb_show /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "SHOW_CB", "NONEEDED", operation)
		end

	set_cb_tray_click (act: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER, INTEGER], STRING])
		local
			operation: INTEGER
		do
			cb_trayclick := act

			if cb_trayclick /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "TRAYCLICK_CB", "NONEEDED", operation)
		end

	set_cb_focus (act: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER], STRING])
		-- Called when the dialog or any of its children gets the focus, or when 
		-- another dialog or any control in another dialog gets the focus. It is
		-- called after the common callbacks GETFOCUS_CB and KILLFOCUS_CB.
		local
			operation: INTEGER
		do
			cb_focus := act

			if cb_focus /= Void then
				operation := 1
			else
				operation := 0
			end
			
			iup_open.set_callback (Current, "FOCUS_CB", "NONEEDED", operation)
		end

	-- Validations

	is_valid_size (width, height: STRING): BOOLEAN
		local
			widths, heights: BOOLEAN
		do
			if width.is_equal("NULL") or
				width.is_equal("FULL") or
				width.is_equal("HALF") or
				width.is_equal("THIRD") or
				width.is_equal("QUARTER") or
				width.is_equal("EIGHTH") then
				widths := True
			elseif width.is_integer and width.to_integer >= 0 then
				widths := True
			else
				widths := False
			end

			if height.is_equal("NULL") or
				height.is_equal("FULL") or
				height.is_equal("HALF") or
				height.is_equal("THIRD") or
				height.is_equal("QUARTER") or
				height.is_equal("EIGHTH") then
				heights := True
			elseif height.is_integer and height.to_integer >= 0 then
				heights := True
			else
				heights := False
			end

			if widths and heights then
				Result := True
			else
				Result := False
			end
		end

	is_valid_type (type: STRING): BOOLEAN
		do
			if type.is_equal("TILEHORIZONTAL") or
				type.is_equal("TILEVERTICAL") or
				type.is_equal("CASCADE") or
				type.is_equal("ICON") then
				Result := True
			else
				Result := False
			end
		end

feature {IUP}

	execute_map: STRING
		do
			if attached cb_map as int_cb then
				Result := int_cb.item([Current])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_unmap: STRING
		do
			if attached cb_unmap as int_cb then
				Result := int_cb.item([Current])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_destroy: STRING
		do
			if attached cb_destroy as int_cb then
				Result := int_cb.item([Current])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_getfocus: STRING
		do
			if attached cb_getfocus as int_cb then
				Result := int_cb.item([Current])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_killfocus: STRING
		do
			if attached cb_killfocus as int_cb then
				Result := int_cb.item([Current])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_enterwindow: STRING
		do
			if attached cb_enterwindow as int_cb then
				Result := int_cb.item([Current])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_leavewindow: STRING
		do
			if attached cb_leavewindow as int_cb then
				Result := int_cb.item([Current])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_k_any (c: INTEGER): STRING
		do
			if attached cb_k_any as int_cb then
				Result := int_cb.item([Current, c])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_help
		do
			if attached cb_help as int_cb then
				int_cb.call([Current])
			end
		end

	execute_close: STRING
		do
			if attached cb_close as int_cb then
				Result := int_cb.item([Current])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_copydata (cmdline: STRING; size: INTEGER): STRING
		do
			if attached cb_copydata as int_cb then 
				Result := int_cb.item([Current, cmdline, size])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_dropfiles (filename: STRING; num: INTEGER; x: INTEGER; y: INTEGER): STRING
		do
			if attached cb_dropfiles as int_cb then
				Result := int_cb.item([Current, filename, num, x, y])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_mdiactivate: STRING
		do
			if attached cb_mdiactivate as int_cb then
				Result := int_cb.item([Current])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_move (x: INTEGER; y: INTEGER): STRING
		do
			if attached cb_move as int_cb then
				Result := int_cb.item([Current, x, y])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_resize (width: INTEGER; height: INTEGER): STRING
		do
			if attached cb_resize as int_cb then
				Result := int_cb.item([Current, width, height])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_show (state: STRING): STRING
		do
			if attached cb_show as int_cb then
				Result := int_cb.item([Current, state])
			else
				Result := "IUP_DEFAULT"
			end
		end
	
	execute_trayclick (but: INTEGER; pressed: INTEGER; dclick: INTEGER): STRING
		do
			if attached cb_trayclick as int_cb then
				Result := int_cb.item([Current, but, pressed, dclick])
			else
				Result := "IUP_DEFAULT"
			end
		end

	execute_focus (focus: INTEGER): STRING
		do
			if attached cb_focus as int_cb then
				Result := int_cb.item([Current, focus])
			else
				Result := "IUP_DEFAULT"
			end
		end

feature {IUP}

	dialog_widget (a_dialog: POINTER)
		do
			set_widget(a_dialog)
		end
						
feature {NONE}

	-- Callbacks

	cb_map: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
	cb_unmap: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
	cb_destroy: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
	cb_getfocus: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
	cb_killfocus: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
	cb_enterwindow: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
	cb_leavewindow: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
	cb_k_any: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER], STRING]
	cb_help: detachable PROCEDURE[TUPLE[IUP_DIALOG]]

	cb_close: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
	cb_copydata: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING, INTEGER], STRING]
	cb_dropfiles: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING, INTEGER, INTEGER, INTEGER], STRING]
	cb_mdiactivate: detachable FUNCTION[TUPLE[IUP_DIALOG], STRING]
	cb_move: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER], STRING]
	cb_resize: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER], STRING]
	cb_show: detachable FUNCTION[TUPLE[IUP_DIALOG, STRING], STRING]
	cb_trayclick: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER, INTEGER, INTEGER], STRING]
	cb_focus: detachable FUNCTION[TUPLE[IUP_DIALOG, INTEGER], STRING]
	
	-- Internals
	
	int_dialog (wdt: POINTER): detachable POINTER
		external
			"C inline use %"eiffel-iup.h%""
      alias
			"return IupDialog ($wdt);"
      end

end -- class IUP_DIALOG

-- The MIT License (MIT)

-- Copyright (c) 2016, 2017, 2018, 2019, 2020 by German A. Arias

-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
